﻿#pragma once

#include <functional>

#include <xy/ais/msg.h>

namespace xy
{

namespace ais
{

class object
{
  public:
    enum Status
    {
        Shown,
        Hidden,
        Hovered,
        Pressed,
        Dead
    };

  protected:
    Status m_status{Shown};
    object *m_parent{nullptr};
    std::shared_ptr<renderer> m_renderer;
    std::vector<std::shared_ptr<object>> m_children;

  public:
    /**
     * @brief 默认构造函数
     *
     */
    explicit object() = default;

    /**
     * @brief 析构函数
     *
     */
    virtual ~object() = default;

    /**
     * @brief 碰撞检测接口
     *
     * @param[in] msg
     */
    virtual bool collision(msg_mouse *msg);

    /**
     * @brief 设置父对象
     *
     * @param[in] parent
     */
    void set_parent(object *parent);

    /**
     * @brief 添加子对象
     *
     * @param[in] child
     */
    void add_child(std::shared_ptr<object> child);

    /**
     * @brief 获得状态
     *
     * @return Status
     */
    Status status() const;

    /**
     * @brief 设置状态
     *
     * @param[in] status
     */
    void set_status(Status status);

    /**
     * @brief 消息处理函数
     *
     * @param[in] msg
     */
    void handle_msg(std::shared_ptr<msg> msg);

    /**
     * @brief 访问接口
     *
     * @param[in] msg
     */
    virtual void visit(msg_init *msg);
    virtual void visit(msg_update *msg);
    virtual void visit(msg_paint *msg);
    virtual void visit(msg_visible *msg);
    virtual void visit(msg_move *msg);
    virtual void visit(msg_mouse *msg);
    virtual void visit(msg_destroy *msg);
};

template <class Derived> inline void msg_impl<Derived>::accept(object *visitor)
{
    // 静态判断，节省运行时开销
    visitor->visit(static_cast<Derived *>(this));
}

} // namespace ais

} // namespace xy
